package com.cennavi.bigdata.baotou.util;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;
import net.sf.json.util.PropertyFilter;
import org.apache.commons.collections.CollectionUtils;

import java.util.*;

/**
 * jong序列化器
 * 
 */
public class JsonUtils {
	/**
	 * map转换json
	 * 
	 * @param map
	 *            map集合
	 * @return 返回转换后的json串
	 */
	public static String map2JSonStr(Map<?, ?> map) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		return toJsonObject(map, excludeProperties, null).toString();
	}

	/**
	 * 将对象转换为json string，使用上面定义的的日期格式
	 * 
	 * @param obj
	 *            待转换对象
	 * @return JSONObject 转换后的JSONObject对象
	 */
	public static JSONObject convertToJsonfromObject(Object obj) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		return toJsonObject(obj, excludeProperties, null);
	}

	/**
	 * 将对象转换为json string，使用上面定义的的日期格式
	 * 
	 * @param obj
	 *            待转换对象
	 * @return JSONArray 转换后的JSONArray对象
	 */
	public static JSONArray convertToJsonfromArray(Object obj) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		return toJsonArray(obj, excludeProperties, null);
	}

	/**
	 * map转换json
	 * 
	 * @param map
	 *            map集合
	 * @param properties
	 *            排除属性
	 * @return 返回转换后的json串
	 */
	public static String map2JSonStr(Map<?, ?> map, String[] properties) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		String[] allProperties = copyArrays(properties, excludeProperties);
		JSONObject jsonObject = toJsonObject(map, allProperties, null);
		return jsonObject.toString();
	}

	/**
	 * 将对象转换为json string，使用上面定义的的日期格式
	 * 
	 * @param obj
	 *            待转换对象
	 * @param properties
	 *            排除属性
	 * @return JSONObject 转换后的JSONObject对象
	 */
	public static JSONObject convertToJsonfromObject(Object obj, String[] properties) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		String[] allProperties = copyArrays(properties, excludeProperties);
		return toJsonObject(obj, allProperties, null);
	}

	/**
	 * 对象序列化器
	 * 
	 * @param obj
	 *            待序列化对象
	 * @param properties
	 *            排除字段
	 * @return json
	 */
	public static JSONArray convertToJsonfromArray(Object obj, String[] properties) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		String[] allProperties = copyArrays(properties, excludeProperties);
		return toJsonArray(obj, allProperties, null);
	}

	/**
	 * map转换json
	 * 
	 * @param map
	 *            map集合
	 * @param properties
	 *            排除属性
	 * @param jsonConfig
	 *            序列化配置
	 * @return 返回转换后的json串
	 */
	public static String map2JSonStr(Map<?, ?> map, String[] properties, JsonConfig jsonConfig) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		String[] allProperties = copyArrays(properties, excludeProperties);
		JSONObject jsonObject = toJsonObject(map, allProperties, jsonConfig);
		return jsonObject.toString();
	}

	/**
	 * 将对象转换为json string，使用上面定义的的日期格式
	 * 
	 * @param obj
	 *            待转换对象
	 * @param properties
	 *            排除属性
	 * @param jsonConfig
	 *            序列化配置
	 * @return JSONObject 转换后的JSONObject对象
	 */
	public static JSONObject convertToJsonfromObject(Object obj, String[] properties, JsonConfig jsonConfig) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		String[] allProperties = copyArrays(properties, excludeProperties);
		return toJsonObject(obj, allProperties, jsonConfig);
	}

	/**
	 * 对象序列化器
	 * 
	 * @param obj
	 *            待序列化对象
	 * @param properties
	 *            排除字段
	 * @param jsonConfig
	 *            序列化配置
	 * @return json
	 */
	public static JSONArray convertToJsonfromArray(Object obj, String[] properties, JsonConfig jsonConfig) {
		String[] excludeProperties = new String[] { "handler", "hibernateLazyInitializer" };
		String[] allProperties = copyArrays(properties, excludeProperties);
		return toJsonArray(obj, allProperties, jsonConfig);
	}

	/**
	 * 将对象转换成jsonObject
	 * 
	 * @param object
	 *            待转换对象
	 * @param properties
	 *            排除属性集合
	 * @param jsonConfig
	 *            序列化配置
	 * @return json
	 */
	private static JSONObject toJsonObject(Object object, String[] properties, JsonConfig jsonConfig) {
		if (jsonConfig == null) {
			jsonConfig = new JsonConfig();
		}
		DateJsonValueProcessor beanProcessor = new DateJsonValueProcessor(DEFAULT_DATE_TIME_PATTERN);
		jsonConfig.registerJsonValueProcessor(Date.class, beanProcessor);
		jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);// 解决循环依赖问题
//		jsonConfig.setExcludes(properties); // 解决hibernate懒加载问题
		
		// 使用扩展的过滤条件以支持类+属性的过滤参数
		jsonConfig.setJsonPropertyFilter(new FieldworkPropertyFilter(properties));

		return JSONObject.fromObject(object, jsonConfig);
	}

	/**
	 * 将对象转换成jsonArray
	 * 
	 * @param obj
	 *            待转换对象
	 * @param properties
	 *            排除属性集合
	 * @param jsonConfig
	 *            序列化配置
	 * @return jsonArray
	 */
	private static JSONArray toJsonArray(Object obj, String[] properties, JsonConfig jsonConfig) {
		if (jsonConfig == null) {
			jsonConfig = new JsonConfig();
		}
		DateJsonValueProcessor beanProcessor = new DateJsonValueProcessor(DEFAULT_DATE_TIME_PATTERN);
		jsonConfig.registerJsonValueProcessor(Date.class, beanProcessor);
		jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);// 解决循环依赖问题
		jsonConfig.setExcludes(properties); // 解决hibernate懒加载问题

		// 使用扩展的过滤条件以支持类+属性的过滤参数
		//jsonConfig.setJsonPropertyFilter(new FieldworkPropertyFilter(properties));
		//设置过滤json格式
        PropertyFilter filter = new PropertyFilter() {
            public boolean apply(Object object, String fieldName, Object fieldValue) {
	            if(fieldValue instanceof List){
	                List<Object> list = (List<Object>) fieldValue;
	                if (list.size()==0) { return true; }
	            }
	            return null == fieldValue || "".equals(fieldValue);
            }
        };
        jsonConfig.setJsonPropertyFilter(filter);

		
		JSONArray jsonArray = JSONArray.fromObject(obj, jsonConfig);
		return jsonArray;
	}

	/**
	 * 拷贝一个数组到当前数组
	 * 
	 * @param source
	 *            源属性
	 * @param dest
	 *            目标属性
	 * @return 最终属性集合
	 */
	public static String[] copyArrays(String[] source, String[] dest) {
		if (source != null && source.length > 0) {
			String[] all = new String[source.length + dest.length];
			System.arraycopy(source, 0, all, 0, source.length);
			System.arraycopy(dest, 0, all, source.length, dest.length);
			return all;
		} else {
			return source;
		}
	}

	/**
	 * 转化一个json为对象
	 * @param json 字符串
	 * @param excludes 排除字段
	 * @param rootClass 根对象
	 * @param propertyFilter 属性过滤器，用以对一个或者几个对象特殊处理
	 * @return java对象
	 */
	public static Object convertJsonToObject(String json,String[] excludes,Class rootClass,PropertyFilter propertyFilter){
		if(StringUtils.isBlank(json)){
			return null;
		}
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { DEFAULT_DATE_PATTERN, DEFAULT_DATE_TIME_PATTERN }));
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(excludes);
		jsonConfig.setJavaPropertyFilter(propertyFilter);
		jsonConfig.setRootClass(rootClass);
		if(json.startsWith("[")){
			JSONArray jsonArray=JSONArray.fromObject(json, jsonConfig);
			return JSONArray.toArray(jsonArray,jsonConfig);
		}else{
			JSONObject jsonObject=JSONObject.fromObject(json, jsonConfig);
			return JSONObject.toBean(jsonObject,jsonConfig);
		}
	}
	
	/**
	 * 转化一个json为对象  时间格式为 DATE_TIME
	 * @param json 字符串
	 * @param excludes 排除字段
	 * @param rootClass 根对象
	 * @param propertyFilter 属性过滤器，用以对一个或者几个对象特殊处理
	 * @return java对象
	 */
	public static Object convertJsonToObjectDT(String json,String[] excludes,Class rootClass,PropertyFilter propertyFilter){
		if(StringUtils.isBlank(json)){
			return null;
		}
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(excludes);
		jsonConfig.setJavaPropertyFilter(propertyFilter);
		jsonConfig.setRootClass(rootClass);
		//jsonConfig.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor());
		if(json.startsWith("[")){
			JSONArray jsonArray=JSONArray.fromObject(json, jsonConfig);
			return JSONArray.toArray(jsonArray,jsonConfig);
		}else{
			JSONObject jsonObject=JSONObject.fromObject(json, jsonConfig);
			return JSONObject.toBean(jsonObject,jsonConfig);
		}
	}
	
	/**
	 * 格式化字符串为json对象格式
	 * @param datas
	 * @return
	 */
	public static String jsonFormat(String datas) {
		if(!StringUtils.isBlank(datas)){
	        return datas.replace("\\\"","\"").replace("\"{","{").replace("}\"","}").replace("\"[","[").replace("]\"","]");
		}else{
			return "";
		}
    }
	
	// 常量属性

	/** 默认格式化字符串 */
	public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
	/** 默认格式化字符串 */
	public static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
	static {
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { DEFAULT_DATE_TIME_PATTERN,DEFAULT_DATE_PATTERN}));
	}

}

/**
 * 项目名称：mgisx-utils
 * 类名称：FieldworkPropertyFilter
 * 类描述：定制的属性过滤器，支持 className:attributName形式过滤
 * 创建时间：2015年4月2日下午8:36:48
 * 修改备注：
 */
class FieldworkPropertyFilter implements PropertyFilter {
	/** 过滤条件 */
	Set<String> excludeInfo = new HashSet<String>();
	/**
	 * 默认构造函数
	 * @param excludes 传入的过滤条件
	 */
	public FieldworkPropertyFilter(String[] excludes) {
		if (excludes != null){
			CollectionUtils.addAll(excludeInfo, excludes);
		}
	}
	@Override
	public boolean apply(Object obj, String name, Object value) {
		String className = obj.getClass().getName();
		int assist = className.indexOf("_$$_javassist_"); 
		if (assist > 0){
			className = className.substring(0, assist);
		}
		return excludeInfo.contains(name) ^ excludeInfo.contains(className + ":" + name);
	}
}